//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Resource Application Block
//===============================================================================

using System;
using Microsoft.Practices.EnterpriseLibrary.Configuration.Design;
using EntLibContrib.Resource.Providers;
using EntLibContrib.Resource.Properties;

namespace EntLibContrib.Resource.Configuration.Design
{
	/// <summary>
	/// This class builds the configuration data from a hierarchy node structure
	/// to populate the configuration settings from the console.
	/// </summary>
	public class ResourceSettingsBuilder
	{
		#region Fields
		private ResourceSettingsNode resourceSettingsNode;
		private IConfigurationUIHierarchy hierarchy;
		private ResourceSettings resourceConfiguration;
		#endregion

		#region Construction
		/// <summary>
		/// Initializes a new instance of the <see cref="ResourceSettingsBuilder"/> class.
		/// </summary>
		/// <param name="serviceProvider">The service provider.</param>
		/// <param name="resourceSettingsNode">The resource settings node.</param>
		public ResourceSettingsBuilder (IServiceProvider serviceProvider, ResourceSettingsNode resourceSettingsNode)
		{
			this.resourceSettingsNode = resourceSettingsNode;
			hierarchy = ServiceHelper.GetCurrentHierarchy(serviceProvider);
			resourceConfiguration = new ResourceSettings();
		}
		#endregion

		#region Public Methods
		/// <summary>
		/// Builds the configuration data for the resource manager settings.
		/// </summary>
		/// <returns></returns>
		public ResourceSettings Build ()
		{
			resourceConfiguration.DefaultResourceManager = resourceSettingsNode.DefaultResourceManager.Name;
			if (!resourceSettingsNode.RequirePermission)	// don't set if false
				resourceConfiguration.SectionInformation.RequirePermission = resourceSettingsNode.RequirePermission;

			BuildResourceProviders();

			BuildResourceManagers();

			return resourceConfiguration;
		}
		#endregion

		#region Private Methods
		private void BuildResourceManagers ()
		{
			foreach ( ResourceManagerBaseNode managerNode in hierarchy.FindNodesByType(resourceSettingsNode, typeof(ResourceManagerBaseNode)) )
			{
				ResourceManagerDataBase resourceManagerDataBase = managerNode.ResourceManagerData;

				// special case for ResourceManagerData, set up the referenced storage as child nodes
				ResourceManagerData resourceManagerData = resourceManagerDataBase as ResourceManagerData;
				if (resourceManagerData != null)
				{
					ResourceProviderBaseNode providerNodeForManager = (ResourceProviderBaseNode)hierarchy.FindNodeByType(managerNode, typeof(ResourceProviderBaseNode));
					resourceManagerData.ResourceProvider = (providerNodeForManager == null) ? InternalResources.AssemblyResourceProviderName : providerNodeForManager.Name;

					if (resourceManagerData.ResourceProvider == InternalResources.AssemblyResourceProviderName && !resourceConfiguration.ResourceProviders.Contains(InternalResources.AssemblyResourceProviderName))
					{
						resourceConfiguration.ResourceProviders.Add(new ResourceProviderDataBase(InternalResources.AssemblyResourceProviderName, typeof(AssemblyResourceProvider)));
					}
				}

				resourceConfiguration.ResourceManagers.Add(resourceManagerDataBase);
			}
		}

		private void BuildResourceProviders ()
		{
			foreach ( ResourceProviderBaseNode resourceProviderNode in hierarchy.FindNodesByType(resourceSettingsNode, typeof(ResourceProviderBaseNode)) )
			{
				ResourceProviderDataBase resourceProviderData = resourceProviderNode.ResourceProviderData;

				resourceConfiguration.ResourceProviders.Add(resourceProviderData);
			}
		}
		#endregion
	}
}